#ifdef UTIL_PLATFORM_LINUX

#include "lang/Thread.h"
#include "pthread.h"
#include "sched.h"
#include "unistd.h"
#include <sys/resource.h>
#include <stdexcept>

namespace yzrilyzr_lang {
    void Thread::setPriority(Priority p) {
        pthread_t threadHandle = reinterpret_cast<pthread_t>(mHandle);

        // 方法1: 尝试使用实时调度策略（需要权限）
        int policy = SCHED_OTHER;
        int priority_value = 0;

        // 根据优先级选择策略和参数
        switch (p) {
            case LOW:
                policy = SCHED_OTHER;
                priority_value = 0;
                break;
            case NORMAL:
                policy = SCHED_OTHER;
                priority_value = 0;
                break;
            case HIGH:
                // 尝试使用实时调度策略获得更高优先级
                policy = SCHED_RR;
                // 设置一个合理的实时优先级（不是最高，避免系统问题）
                priority_value =
                        (sched_get_priority_max(policy) + sched_get_priority_min(policy)) / 2;
                break;
        }

        sched_param params;
        params.sched_priority = priority_value;

        // 尝试设置调度参数
        int result = pthread_setschedparam(threadHandle, policy, &params);

        if (result == 0) {
            // 成功设置了调度策略
            return;
        }

        // 如果设置失败（通常是因为没有权限），回退到nice值
        if (result == EPERM || result == EINVAL) {
            int nice_value = 0;

            switch (p) {
                case LOW:
                    nice_value = 10;    // 较低优先级
                    break;
                case NORMAL:
                    nice_value = 0;     // 默认优先级
                    break;
                case HIGH:
                    nice_value = -10;   // 较高优先级
                    break;
            }

            // 获取线程的PID（在Linux中，线程也是轻量级进程）
            pid_t tid = gettid();

            // 设置nice值
            if (setpriority(PRIO_PROCESS, tid, nice_value) != 0) {
                // nice值设置也失败，这是正常情况，不需要抛出异常
                // 普通程序可能没有权限设置负的nice值
            }
        }
    }

    void Thread::setName(const String &name) {
        pthread_t threadHandle = reinterpret_cast<pthread_t>(mHandle);
        // 使用pthread_setname_np，注意长度限制
        char truncated_name[16];
        snprintf(truncated_name, sizeof(truncated_name), "%.15s", name.c_str());
        pthread_setname_np(threadHandle, truncated_name);
    }

    std::shared_ptr<Thread> Thread::currentThread() {
        return std::make_shared<Thread>(
                reinterpret_cast<yzrilyzr_lang_thread_handle>(pthread_self()));
    }

    void Thread::join() {
        if (mHandle == 0) {
            throw std::runtime_error("Thread already joined or not started");
        }

        pthread_t threadHandle = reinterpret_cast<pthread_t>(mHandle);
        int result = pthread_join(threadHandle, nullptr);

        if (result != 0) {
            if (result == ESRCH) {
                throw std::runtime_error("Thread does not exist");
            } else if (result == EINVAL) {
                throw std::runtime_error("Thread is not joinable");
            } else if (result == EDEADLK) {
                throw std::runtime_error("Deadlock detected");
            } else {
                throw std::runtime_error("Failed to join thread");
            }
        }

        mHandle = 0; // 标记线程已结束
    }

    // 添加gettid()函数（Linux特定）
#ifndef __NR_gettid
#define __NR_gettid 186
#endif

    static pid_t gettid() {
        return syscall(__NR_gettid);
    }
}
#endif